# -*- coding: utf-8 -*-
#
# File: ARFilePreview/adapters.py
#



__author__ = """adam <contact@atreal.net>"""
__docformat__ = 'plaintext'
__licence__ = 'GPL'

import re
import types

from zope.interface import implements
from zope.component.interfaces import ComponentLookupError

from zope.annotation.interfaces import IAnnotations

from BTrees.OOBTree import OOBTree
from Products.CMFCore.utils import getToolByName
from Products.ARFilePreview.interfaces import IPreviewable,ICountable,ITrackDownload
from Products.CMFPlone.CatalogTool import registerIndexableAttribute

fmt = '%Y/%m/%d %H:%M:%S'
from datetime import datetime

class ToTrackDownload(object):
    implements(ITrackDownload)
    def __init__(self,context):
        self.key = "downloadinfo"
        self.context = context
        self.annotations = IAnnotations(context)
        if not self.annotations.get(self.key, None):
            self.annotations[self.key] = 1
    def setDldCount(self,num=1):
        self.annotations[self.key] = num
    def getDldCount(self):
        number = self.annotations[self.key]
        return number
    def updateDldCount(self):
        self.annotations[self.key] = self.annotations[self.key] + 1 
    def download_url(self):
        pass           
class ToCountableObject(object):
    implements(ICountable)
    def __init__(self,context):
        self.key = "previewcountnum"
        self.context = context
        self.annotations = IAnnotations(context)
        if not self.annotations.get(self.key, None):
            self.annotations[self.key] = 1
    def setCount(self,num):
        self.annotations[self.key] = num
    def getCount(self):
        number = self.annotations[self.key]
        return number
    def updateCount(self):
        self.annotations[self.key] = self.annotations[self.key] + 1                       
            
class ToPreviewableObject( object ):    
    implements( IPreviewable )    
    _re_imgsrc = re.compile('<[iI][mM][gG]([^>]*) [sS][rR][cC]="([^">]*)"([^>]*)>')    
    class _replacer(object):        
        def __init__(self, sublist, instance):
            self.sublist = sublist
            self.instance = instance        
        def __call__(self, match):
            prefix = match.group(1)
            inside = match.group(2)
            postfix = match.group(3)
            # patch inside
            if inside.startswith('./'):
                # some .swt are converted with this prefix
                inside = inside[2:]
            if inside in self.sublist:
                # convert elems that are known images 
                inside = '%s/@@preview_provider/%s' % (self.instance.getId(), inside)
            result = '<img%s src="%s"%s>' % (prefix, inside, postfix)
            return result    
    def __init__(self, context):
        self.key         = 'htmlpreview'
        self.context     = context
        self.annotations = IAnnotations(context)
        if not self.annotations.get(self.key, None):
            self.annotations[self.key] = OOBTree()
        if not self.annotations[self.key].get('html', None):
            self.annotations[self.key]['html'] = u""
        if not self.annotations[self.key].get('subobjects', None):
            self.annotations[self.key]['subobjects'] = OOBTree()
    
    def hasPreview(self):
        return bool(len(self.annotations[self.key]['html']))
    
    def setPreview(self, preview):
        if isinstance(preview, types.UnicodeType):
            preview = preview
        else:                                  
            preview = preview.decode("utf-8")
        self.annotations[self.key]['html'] = preview
        self.context.reindexObject()
    
    def getPreview(self, mimetype="text/html"):
        data = self.annotations[self.key]['html']
        if mimetype!="text/html" and data is not None and data != '' :
            transforms = getToolByName(self.context, 'portal_transforms')
            filename = self.context.getPrimaryField().getAccessor(self.context)().filename+".html"
            return str(transforms.convertTo(mimetype, data.encode('utf-8'), mimetype="text/html", filename = filename)).decode('utf-8')
        return data
    
    def setSubObject(self, name, data):
        mtr = self.context.mimetypes_registry
        mime = mtr.classify(data, filename=name)
        mime = str(mime) or 'application/octet-stream'
        self.annotations[self.key]['subobjects'][name] = (data, mime)
    
    def getSubObject(self, id):
        if id in self.annotations[self.key]['subobjects'].keys():
            return self.annotations[self.key]['subobjects'][id]
        else:
            raise AttributeError
    
    def clearSubObjects(self):
        self.annotations[self.key]['subobjects'] = OOBTree()
    
    def updateModified(self):
        self.context.setModificationDate(datetime.now().strftime(fmt))
    def buildAndStorePreview(self):
#        import pdb
#        pdb.set_trace()
        self.clearSubObjects()
        transforms = getToolByName(self.context, 'portal_transforms')
        fileobj = self.context.getPrimaryField().getAccessor(self.context)()
        if isinstance(fileobj,str):
##        if type(fileobj)==type("i am a string"):
##            self.setPreview(u"为了呈现预览，需要重新编辑并保存文档")
            return
        tmp=self.context.get_data()
        if isinstance(tmp, types.UnicodeType):
            tmp = tmp.encode("utf-8")
        else:
            tmp = tmp           
    
        if len(tmp) > 80000:
            self.setPreview(u"本文件已超过预览大小限制；系统取消了文件预览功能！")
            return
        data = transforms.convertTo('text/html', tmp, filename=fileobj.filename)        
        if data is None:
            self.setPreview(u"can not find converter")
            return        
        #get the html code
        html_converted = data.getData()
        #update internal links
        #remove bad character '\xef\x81\xac' from HTMLPreview
        html_converted = re.sub('\xef\x81\xac', "", html_converted)
        # patch image sources since html base is that of our parent
        subobjs = data.getSubObjects()
        if len(subobjs)>0:
            for id, data in subobjs.items():
                self.setSubObject(id, data)
            html_converted = self._re_imgsrc.sub(self._replacer(subobjs.keys(), self.context), html_converted)
        #store the html in the HTMLPreview field for preview
        
        try:
            self.setPreview(html_converted.decode('utf-8'))
        except:
            self.setPreview(u"本文件中有非法字符，不能转换为HTML预览！")
#            self.setPreview(html_converted.decode('utf-8'))
        self.context.reindexObject()

def previewIndexWrapper(object, portal, **kwargs):
    data = object.SearchableText()
    try:
        obj = IPreviewable(object)
        preview = obj.getPreview(mimetype="text/plain")
        return " ".join([data, preview.encode('utf-8')])
    except (ComponentLookupError, TypeError, ValueError):
        # The catalog expects AttributeErrors when a value can't be found
        return data

registerIndexableAttribute('SearchableText', previewIndexWrapper)
